package com.logic.landseaserver.service.callback;

import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.logic.landseaserver.common.LandeaConstants.DdingConstant;
import com.logic.landseaserver.common.LandseaErrorMessageEnum;
import com.logic.landseaserver.common.exception.LandseaException;
import com.logic.landseaserver.domain.AbstractCallbackEvt;
import com.logic.landseaserver.domain.DdingEventCallbackEvt;
import com.logic.landseaserver.domain.DdingRoomSync;
import com.logic.landseaserver.domain.Room;
import com.logic.landseaserver.persistence.read.DdingRoomSyncReadMapper;
import com.logic.landseaserver.persistence.read.RoomReadMapper;
import com.logic.landseaserver.persistence.write.DdingRoomSyncWriteMapper;

@Service(DdingConstant.CALLBACK_EVNET_SERVICE_NAME_PREFIX + "deviceInstall")
public class DdingDeviceInstallEvtHandler implements IEventCallbackHandler
{
    private static final Logger LOG = LoggerFactory.getLogger(DdingDeviceInstallEvtHandler.class);
    
    @Autowired
    private RoomReadMapper roomReadMapper;
    
    @Autowired
    private DdingRoomSyncReadMapper ddingRoomSyncReadMapper;
    
    @Autowired
    private DdingRoomSyncWriteMapper ddingRoomSyncWriteMapper;
    
    @SuppressWarnings("unchecked")
    @Override
    public Object process(AbstractCallbackEvt callbackEvent)
        throws LandseaException
    {
        try
        {
            DdingEventCallbackEvt event = (DdingEventCallbackEvt)callbackEvent;
            
            // 获取detail
            Object detailObject = event.getDetail();
            if (null == detailObject)
            {
                LOG.error("eventCallback|DdingDeviceInstallEvtHandler|Error|detailObject is empty.");
                throw LandseaException.createException(LandseaErrorMessageEnum.DDINGLOCK_CALLBACK_PARAM_ERROR);
            }
            
            Map<String,Object> detailMap = (Map<String,Object>)detailObject;
            String type = String.valueOf(detailMap.get("type"));
            
            // type枚举 网关: 1,门锁: 4,电表 : 5,采集器: 6
            // 目前只处理type为4
            if (DdingConstant.DEVICETYPE_DOOR_LOCK.equals(type))
            {
                processInstallLock(event);
            }
            else
            {
                // 若不是门锁，记录日志返回
                LOG.error("eventCallback|DdingDeviceInstallEvtHandler|Warning|deviceType is not 4 so igonre it.");
                return null;
            }
            
            return null;
        }
        catch (LandseaException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            LOG.error("eventCallback|DdingDeviceInstallEvtHandler|handle callback event failed.", e);
            throw LandseaException
                .createException(LandseaErrorMessageEnum.DDINGLOCK_CALLBACK_PROCESS_INSTALL_DEVICE_ERROR, e);
        }
    }
    
    // 处理安装门锁回调
    private void processInstallLock(DdingEventCallbackEvt event)
        throws LandseaException
    {
        String projectId = event.getHome_id();
        String roomId = event.getRoom_id();
        String uuid = event.getUuid();
        
        if (StringUtils.isEmpty(roomId) || StringUtils.isEmpty(projectId))
        {
            LOG.error("eventCallback|processInstallLock|Error|roomId or homeId is empty.");
            throw LandseaException.createException(LandseaErrorMessageEnum.DDINGLOCK_CALLBACK_PARAM_ERROR);
        }
        
        // 检查room是否合法
        Room room = roomReadMapper.selectRoomInfo(Integer.parseInt(roomId));
        
        if (null == room)
        {
            LOG.error("eventCallback|processInstallLock|Error|room not exists with roomId=" + roomId);
            throw LandseaException.createException(LandseaErrorMessageEnum.DDINGLOCK_ROOM_NOT_EXISTS_ERROR);
        }
        
        // 查询同步记录
        DdingRoomSync ddingRoomSync = ddingRoomSyncReadMapper.selectByPrimaryKey(room.getId());
        
        if (null == ddingRoomSync || DdingConstant.SYNCSTATE_YES != ddingRoomSync.getSyncState())
        {
            LOG.error("eventCallback|processInstallLock|Error|roomId=" + roomId + " not sync dding system.");
            throw LandseaException.createException(LandseaErrorMessageEnum.DDINGLOCK_ROOM_NONESYNC_ERROR);
        }
        
        // 更新
        try
        {
            // 更新数据库
            DdingRoomSync updateRecord = new DdingRoomSync();
            updateRecord.setRoomId(room.getId());
            updateRecord.setLockState(DdingConstant.LOCK_INSTALL_STATE_SUCCESS);
            //Date installTime = new Date(event.getTime());
            updateRecord.setInstallLockTime(new Date());
            updateRecord.setLockUuid(uuid);
            ddingRoomSyncWriteMapper.updateByPrimaryKeySelective(updateRecord);
        }
        catch (Exception e)
        {
            LOG.error("eventCallback|processInstallLock|Error|update lock info to database failed,roomId=" + roomId, e);
            throw LandseaException.createException(LandseaErrorMessageEnum.DDINGLOCK_UPDATE_ROOM_LOCK_SYNC_ERROR, e);
        }
    }
}
